SuperStrict

Framework BRL.StandardIO

Import BRL.Random

Import Otus.Actor


' Thread-safe wrapper for Print
Function Print(s:String="")
	Global mutex:TMutex = CreateMutex()
	mutex.Lock
	BRL.StandardIO.Print s
	mutex.Unlock
End Function

' Actor types

Type TDownloader Extends TActor
	
	Method Receive:Object(msg:Object)
		Print "Downloading "+msg.ToString()+".tar.gz..."
		Delay Rand(5000)	'Simulate download time
		Print "Downloaded "+msg.ToString()+".tar.gz"
		Return msg
	End Method
	
End Type

Type TExtracter Extends TActorThread
	
	Method Receive:Object(msg:Object)
		Print "Extracting "+msg.ToString()+".tar.gz..."
		Delay Rand(500)	'Simulate extract time
		Print "Extracted "+msg.ToString()+".tar.gz"
		Return msg
	End Method
	
	Method Sleep()
		Delay 1
	End Method
	
End Type

Type TBuilder Extends TActor
	
	Method Receive:Object(msg:Object)
		Print "Building "+msg.ToString()+".build..."
		Delay Rand(2000)	'Simulate build time
		Print "Built "+msg.ToString()+".build"
		Return msg
	End Method
	
End Type

Type TCleaner Extends TActor
	
	Field cleaned:Int
	
	Method Receive:Object(msg:Object)
		Print "Cleaning "+msg.ToString()+"..."
		Delay 10			' Fast
		Print "Cleaned "+msg.ToString()
		cleaned :+ 1
		Return Null
	End Method
	
End Type


Print "Creating actors..."


' Create a pool of up to 5 downloader threads
Local downloader:TDownloader = New TDownloader
Local down_pool:TThreadPool = CreateThreadPool(5)
downloader.SetGroup(down_pool)

' Create a single extracter thread
Local extracter:TExtracter = New TExtracter

' Create a pool of up to 2 builder threads
Local builder:TBuilder = New TBuilder
Local build_pool:TThreadPool = CreateThreadPool(2)
builder.SetGroup(build_pool)

' Create a cleaner actor without a thread
Local cleaner:TCleaner = New TCleaner


Print "Sending work..."


' Set a list of files to download, extract, build and clean up in order
Local files:String[]..
	= ["file1", "file2", "file3", "file4", "file5", "file6", "file7", "file8"]

For Local file:String = EachIn files
	downloader.Send(file).Chain(extracter).Chain(builder).Chain(cleaner)
Next

' Run the cleaner until all is done
While cleaner.cleaned < files.length
	cleaner.Process
Wend


Print "All done."

